#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <cassert>
#include <functional>
#include <pthread.h>

class Thread;
//上下文
class Context
{
public:
    Thread* _this;
    void* _args;
    Context():_this(nullptr),_args(nullptr)
    {}
    ~Context()
    {}
};

class Thread
{
public:
    // using func_t = std::function<void*(void*)>;
    typedef std::function<void*(void*)> func_t;
    const int num = 1024;
public:
    Thread(func_t func,void* args = nullptr,int number = 0)
        :_func(func),_args(args)
    {
        char buffer[num];
        snprintf(buffer,sizeof buffer,"thread-%d",number);
        _name = buffer;

        Context* ctx = new Context();
        ctx->_this = this;
        ctx->_args = _args;
        int n = pthread_create(&_tid,nullptr,start_routine,ctx);
        assert(n == 0);//assert在debug下是存在的，release下是不存在的 
        (void)n;//那么n就是一个定义未被使用的变量，在有些编译器下会报warning
    }
    //在类内创建线程，想让线程执行对应的方法，需要将方法设置为static
    static void* start_routine(void* args)  //类内成员，有缺省参数
    {
        Context* ctx = static_cast<Context*>(args);
        void* ret = ctx->_this->run(ctx->_args);
        delete ctx;
        return ret;
        //静态方法不能调用成员方法或成员变量
        // return _func(_args);
    }
    // void start()
    // {
    //     Context* ctx = new Context();
    //     ctx->_this = this;
    //     ctx->_args = _args;
    //     int n = pthread_create(&_tid,nullptr,start_routine,ctx);
    //     assert(n == 0);//assert在debug下是存在的，release下是不存在的 
    //     (void)n;//那么n就是一个定义未被使用的变量，在有些编译器下会报warning
    // }
    void join()
    {
        int n = pthread_join(_tid,nullptr);
        assert(n == 0);
        (void)n;
    }
    void* run(void* args)
    {
        return _func(args);
    }
    ~Thread()
    {}
private:
    std::string _name;
    pthread_t _tid;
    func_t _func;
    void* _args;
};